/**
 * 
 */
package com.miolr.module.core.config;

import java.beans.PropertyVetoException;
import java.io.IOException;
import java.util.Properties;

import javax.sql.DataSource;

import org.hibernate.SessionFactory;
import org.hibernate.cfg.NamingStrategy;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Profile;
import org.springframework.orm.hibernate4.HibernateTransactionManager;
import org.springframework.orm.hibernate4.LocalSessionFactoryBean;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;

import com.mchange.v2.c3p0.ComboPooledDataSource;

/**
 * @author iday
 * 
 */
@Configuration
@EnableTransactionManagement(proxyTargetClass = true)
@ComponentScan({ "com.miolr.module.core.service", "com.miolr.module.core.dao" })
@Profile("dev")
public class HibernateDevConfig {

	@Bean
	public SessionFactory sessionFactory() {
		Properties hibernateProperties = new Properties();
		hibernateProperties.put("hibernate.dialect",
				"org.hibernate.dialect.H2Dialect");
		hibernateProperties.put("hibernate.query.substitutions",
				"true=1 false=0");
		hibernateProperties.put("hibernate.show_sql", "true");
		hibernateProperties.put("hibernate.use_outer_join", "false");
		hibernateProperties.put("hibernate.bytecode.use_reflection_optimizer",
				"true");
		hibernateProperties.put("hibernate.connection.release_mode", "auto");
		hibernateProperties.put("hibernate.cache.use_second_level_cache",
				"true");
		hibernateProperties.put("hibernate.cache.use_query_cache", "true");
		hibernateProperties.put("hibernate.cache.region.factory_class",
				"org.hibernate.cache.ehcache.EhCacheRegionFactory");
		hibernateProperties
				.setProperty("hibernate.hbm2ddl.auto", "create-drop");
		hibernateProperties.put("hibernate.jdbc.fetch_size", "50");
		hibernateProperties.put("hibernate.jdbc.batch_size", "50");
		
		LocalSessionFactoryBean sessionFactoryBean = new LocalSessionFactoryBean();
		sessionFactoryBean.setDataSource(dataSource());
		sessionFactoryBean.setHibernateProperties(hibernateProperties);
		sessionFactoryBean.setPackagesToScan("com.miolr.module.core.model");
		sessionFactoryBean.setNamingStrategy(namingStrategy());
		try {
			sessionFactoryBean.afterPropertiesSet();
		} catch (IOException e) {
			throw new RuntimeException(e);
		}
		return sessionFactoryBean.getObject();
	}

	@Bean(destroyMethod = "close")
	public DataSource dataSource() {
		ComboPooledDataSource datasource = new ComboPooledDataSource();
		try {
			datasource.setDriverClass("org.h2.Driver");
			datasource.setJdbcUrl("jdbc:h2:mem:miolr");
			datasource.setUser("sa");
			datasource.setPassword(null);
		} catch (PropertyVetoException e) {
			throw new RuntimeException(e);
		}
		return datasource;
	}

	@Bean
	public NamingStrategy namingStrategy() {
		return new MiolrNamingStrategy();
	}

	@Bean
	public PlatformTransactionManager txManager() {
		HibernateTransactionManager txManager = new HibernateTransactionManager();
		txManager.setSessionFactory(sessionFactory());
		txManager.setDataSource(dataSource());
		return txManager;
	}
}
